package com.os.opencv.java.chapter9;

import org.opencv.core.*;
import org.opencv.dnn.Net;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static org.opencv.core.Core.minMaxLoc;
import static org.opencv.dnn.Dnn.*;
import static org.opencv.dnn.Dnn.blobFromImage;

public class OpenCvDnn {

    public static void main(String[] args) throws IOException {

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        /**
         * https://bingbuyu.blog.csdn.net/article/details/78416887?spm=1001.2101.3001.6650.9&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-9-78416887-blog-70982048.235%5Ev39%5Epc_relevant_default_base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-9-78416887-blog-70982048.235%5Ev39%5Epc_relevant_default_base&utm_relevant_index=10
         */
        /*HighGui.imshow("dst1", output);
        HighGui.waitKey(0);*/

        //https://blog.csdn.net/jiangchaobing_2017/article/details/134004283
        //以bvlc_googlenet.caffemodel为例
        String model_txt_file = "/Users/matt/Pictures/bvlc_googlenet.prototxt";//模型的描述文件
        String model_bin_file = "/Users/matt/Pictures/bvlc_googlenet.caffemodel";//模型的权重文件
        String labels_txt_file = "/Users/matt/Pictures/imagenet_labels.txt";

        Mat src = Imgcodecs.imread("/Users/matt/Pictures/smallPotDog.jpg");
        if (src.empty())
        {
            System.out.println("图片源文件为空。。。");
        }
        HighGui.imshow("src", src);
        HighGui.waitKey(0);

        //读取文本标签
        List<String> labels = readLabels(labels_txt_file);

        // 读取网络 包括模型描述文件和和模型文件
        Net net = readNetFromCaffe(model_txt_file, model_bin_file);
        if (net.empty())
        {
            System.out.println("模型文件为空。。。");
        }



        //设置计算后台
        net.setPreferableBackend(DNN_BACKEND_OPENCV);
        //设置支持设备
        net.setPreferableTarget(DNN_TARGET_CPU);

        Mat inputBlob = blobFromImage(src, 1.0, new Size(224, 224), new Scalar(104, 117, 123));
        Mat prob = new Mat();
        for (int i = 0; i < 10; i++)
        {
            net.setInput(inputBlob, "data");
            prob = net.forward("prob");	// 输出为1×1000 1000类的概率
        }
        Mat proMat = prob.reshape(1, 1);	// 单通道 一行

        //https://vimsky.com/examples/detail/java-method-org.opencv.core.Core.minMaxLoc.html
        Core.MinMaxLocResult minMaxLocResult = minMaxLoc(proMat);
        Point classNumber = minMaxLocResult.maxLoc;
        double possibility = minMaxLocResult.maxVal;

        int classidx = (int) classNumber.x;
        System.out.println("current image classification:" + labels.get(classidx));
        System.out.println("current image possible: " + possibility);

        System.exit(0);



    }


    static List<String> readLabels(String txtFilePath) throws IOException {
        List<String> labels = new ArrayList<>();
        FileReader fr = new FileReader(txtFilePath);
        BufferedReader br = new BufferedReader(fr);
        String line;
        while ((line = br.readLine()) != null) {
            labels.add(line);
        }

        br.close();
        fr.close();
        return labels;
    }


}
